//
// Created by nicemoe on 2021/9/5.
//

#ifndef BASE_QueueTp_H
#define BASE_QueueTp_H

template<class Item>
class QueueTp {
private:
    enum {
        Q_SIZE = 10
    };

    class Node {
    public:
        Item item;
        Node *next;

        Node(const Item &i) : item(i), next(0) {}
    };

    Node *front;
    Node *rear;
    int items;
    const int qsize;

    QueueTp(const QueueTp &q) : qsize(0) {}

    QueueTp &operator=(const QueueTp &q) {
        return *this;
    }

public:
    QueueTp(int qs = Q_SIZE);

    ~QueueTp(){};

    bool isEmpty() const {
        return items == 0;
    }

    bool isFull() const {
        return items == qsize;
    }

    int queueCount() const {
        return items;
    }

    bool enQueue(const Item &item);

    bool deQueue(Item &item);
};

template<class Item>
QueueTp<Item>::QueueTp(int qs):qsize(qs) {
    front = rear = 0;
    items = 0;
}

template<class Item>
bool QueueTp<Item>::enQueue(const Item &item) {
    if (isFull()) return false;
    Node *add = new Node(item);
    items++;
    if (front == 0) {
        front = add;
    } else {
        rear->next = add;
    }
    rear = add;
    return true;
}

template<class Item>
bool QueueTp<Item>::deQueue(Item &item) {
    if (front == 0) return false;
    item = front->item;
    items--;
    Node *temp = front;
    front = front->next;
    delete temp;
    if (items == 0) rear = 0;
    return true;

}

#endif //BASE_QueueTp_H
